#pragma once

#include "EventLoop.hpp"


struct Listener
{
public:
    std::shared_ptr<Sock> _listensock_ptr;
    uint16_t _port;

    Listener(uint16_t port)
    : _listensock_ptr(new Sock),
      _port(port)
    {
        _listensock_ptr->Socket();
        _listensock_ptr->Bind(_port);
        _listensock_ptr->Listen();
        lg(Info, "listener create successfully!");
    }

    void Accept(std::weak_ptr<Connection> conn)
    {
        auto connection = conn.lock();
        while (true)
        {
            struct sockaddr_in peer;
            socklen_t len = sizeof(peer);
            int sockfd = ::accept(connection->Sockfd(), (struct sockaddr *)&peer, &len);
            if (sockfd > 0)
            {
                uint16_t peerport = ntohs(peer.sin_port);
                char ipbuf[128];
                inet_ntop(AF_INET, &(peer.sin_addr), ipbuf, sizeof(ipbuf));
                
                SetNonBlock(sockfd);
                connection->_el_ptr.lock()->fds.push(sockfd);
                // AddConnection(sockfd, EVENT_IN,
                //               std::bind(&TcpServer::Recver, this, std::placeholders::_1),
                //               std::bind(&TcpServer::Sender, this, std::placeholders::_1),
                //               std::bind(&TcpServer::Excepter, this, std::placeholders::_1),
                //               ipbuf, peerport);

                lg(Info, "get a new client link, get info-> [%s:%d], sockfd : %d", ipbuf, peerport, sockfd);
            }
            else
            {
                // 事件不就绪，直接结束轮询
                if (errno == EWOULDBLOCK)
                    break;
                // 被信号中断，重新开始轮询
                else if (errno == EINTR)
                    continue;
                else
                    break;
            }
        }
    }
};